<?php


namespace Api\Http\Controllers;


use Api\Jobs\AddPostmanInfo;
use Api\Jobs\MemberProfitTask;
use Api\Service\FilmService;
use Api\Service\YidaService;
use Api\Service\YunyangService;
use Api\traits\ApiResponse;

use Carbon\Carbon;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use EasyWeChat\Pay\Message;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Modules\Common\Models\Area;
use Modules\Film\Models\FilmOrder;
use Modules\Member\Models\Members;
use EasyWeChat\Pay\Application;
use EasyWeChat\MiniApp\Application as MiniApp;
use Modules\Member\Models\MembersPriceLog;
use Modules\Member\Models\MembersProfit;
use EasyWeChat\OfficialAccount\AccessToken;
use Modules\Member\Models\MembersWithdraw;
use Modules\Order\Models\LevelOrders;
use Modules\Order\Models\Orders;
use Modules\Order\Models\RefundRecord;
use Modules\Shop\Models\Pivots\UserHasCoupons;

use EasyWeChat\OfficialAccount\Application as OfficialApp;

/**
 * @group 用户模块
 *
 * @subgroup 用户管理
 * @subgroupDescription CatchAdmin 后台用户管理
 *
 */
class WechatController extends Controller
{
    use ApiResponse;

    public array $config;
    private string $wechatToken;
    private array $miniConfig;

    private array $officialConfig;

    protected string $messageToken = 'xingjushidai';
    protected string $url = 'https://api.susujilianmeng.com';

    public function __construct()
    {

        //支付
        $this->config = [
            'mch_id' => env('MCHID'),
            // 商户证书
            'private_key' => public_path() . '/cert/apiclient_key.pem',
            'certificate' => public_path() . '/cert/apiclient_cert.pem',
            // v3 API 秘钥
            'secret_key' => '762cea6bc6dd7ecd264cecddcf71fd26',

            // v2 API 秘钥 无

            // 平台证书：微信支付 APIv3 平台证书，需要使用工具下载
            // 下载工具：https://github.com/wechatpay-apiv3/CertificateDownloader
            'platform_certs' => [
                // 请使用绝对路径
                public_path() . '/cert/wechatpay_141E7C3415E93BF4155F6B9A5B3AC5A9C14FC8A5.pem',
            ],

            /**
             * 接口请求相关配置，超时时间等，具体可用参数请参考：
             * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php
             */
            'http' => [
                'throw' => false, // 状态码非 200、300 时是否抛出异常，默认为开启
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.mch.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri
            ],
        ];

        //小程序配置
        $this->miniConfig = [
            'app_id' => env('APPID'),
            'secret' => env('SECRET'),
            'use_stable_access_token' => true,
        ];

        $this->officialConfig = [
            'app_id' => env('OFFICIALAPPID'),
            'secret' => env('OFFICIALSECRET'),
            'token' => 'xingjushidai',
            /**
             * OAuth 配置
             *
             * scopes：公众平台（snsapi_userinfo / snsapi_base），开放平台：snsapi_login
             * redirect_url：OAuth授权完成后的回调页地址
             */
            'oauth' => [
                'scopes' => ['snsapi_userinfo'],
                'redirect_url' => 'https://api.susujilianmeng.com/kuaidi/wechat/follow_account',
            ],
            'http' => [
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri
                'retry' => true, // 使用默认重试配置
            ],
        ];

        $this->wechatToken = 'xingjushidai';

    }

    /**
     * @param Request $request
     * 公众号服务器配置
     */
    public function officialConfig(Request $request)
    {
        $str = uniqid();
        $temp['token'] = $this->messageToken;
        $temp['timestamp'] = time();
        $temp['nonce'] = $str;
        ksort($temp);
        $signstr = '';
        foreach ($temp as $k => $v) {
            $signstr .= $v;
        }
        $sign = sha1($signstr);

        $arr['signature'] = $sign;
        $arr['timestamp'] = $temp['timestamp'];
        $arr['nonce'] = rand();
        $arr['echostr'] = uniqid();

        $client = new Client(['timeout' => 5, 'verify' => false]);

        //设置headers头
        $response = $client->get($this->url, [
            'query' => $arr
        ]);

        return $this->success('发送成功');
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];

        $token = 'xingjushidai';
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    /**
     *
     * 微信公众号配置
     */
    public function followAccount()
    {
//                if ($this->checkSignature()) {
//
//            echo $_GET['echostr'];
//            exit();
//        }
        $app = new OfficialApp($this->officialConfig);
        $accessToken = $app->getAccessToken();
        $token = $accessToken->getToken(); // string
        //如果校验通过
        if ($this->checkSignature()) {
            $openid = request()->get('openid');
            $openInfo = Members::where('gzh_open_id', $openid)->first();
            if (empty($openInfo)) {
                // 获取用户基本信息
                $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$token}&openid={$openid}";
                $response = file_get_contents($url);
                $response = stripslashes($response);
                $result = json_decode($response, true);
                $unionId = $result['unionid'];
                // 保存用户信息到数据库或进行其他操作
                $memberInfo = Members::where('union_id', $unionId)->first();
                if (!empty($memberInfo)) {
                    $memberInfo->gzh_open_id = $openid;
                    $memberInfo->save();
                }
            }
            // 如果是关注事件
            $xml = file_get_contents("php://input");
            $postData = (array)simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
            if (isset($postData['MsgType']) && $postData['MsgType'] == 'event' && $postData['Event'] == 'subscribe') {
                // 获取用户的FromUserName，即OpenID
                $openID = $postData['FromUserName'];
                // 回复用户关注成功信息
                $response = [
                    'ToUserName' => $openID,
                    'FromUserName' => 'gh_418531f3178d', // 你的公众号ID
                    'CreateTime' => time(),
                    'MsgType' => 'text',
                    'Content' => 'Hi感谢关注速速寄联盟5折起寄快递，寄啥都便宜戳下方蓝字领新人权益

#小程序://速速寄联盟#小程序://速速寄联盟/HJD7u0MvuPhEVzF

建议用圆通，圆通上门取件效率快哈~速速寄联盟，让您寄快递更便宜',
                ];

                // 将数组转换成XML格式的消息
                $responseXml = '<xml>';
                foreach ($response as $key => $value) {
                    $responseXml .= "<$key><![CDATA[$value]]></$key>";
                }
                $responseXml .= '</xml>';
                // 输出响应消息
                echo $responseXml;

            }

        }

    }

    /**
     * @return \Illuminate\Http\Response
     * 直升v1
     */
    public function levelPayInfo(): \Illuminate\Http\Response
    {
        $userId = $this->getLoginUserId();
        $userInfo = Members::find($userId);
        $level = Members::where('id', $userId)->value('user_level');
        if ($level != 0) {
            return $this->fail('等级不是用户无法升级v1');
        }
        $order = new LevelOrders();
        $orderSn = uniqid();
        $order->order_sn = $orderSn;
        $order->user_id = $userId;
        $order->money = 5.9;
        $orderInfo = $order->save();
        if (!empty($orderInfo)) {
            $app = new Application($this->config);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => env('MCHID'), // <---- 请修改为您的商户号
                "out_trade_no" => $orderSn,
                "appid" => env('APPID'), // <---- 请修改为服务号的 appid
                "description" => " 用户升级",
                "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/level_callback",
                "amount" => [
                    "total" => 590,
                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => $userInfo->open_id, // <---- 请修改为服务号下单用户的 openid
                ]
            ]);
            $prepayId = $response->toArray()['prepay_id'];
            if (empty($prepayId)) {
                return $this->fail('订单信息有误');
            }
            $utils = $app->getUtils();
            $config = $utils->buildMiniAppConfig($prepayId, env('APPID'));
            return $this->data($config);
        } else {
            return $this->fail('未知错误');
        }
    }


    public function getPayInfo(Request $request)
    {
        $orderSn = $request->order_sn;
        $orderInfo = Orders::where('order_sn', $orderSn)->where('status', 0)->first();
        $orderInfo2 = Orders::where('overweight_sn', $orderSn)->first();
        $userInfo = $this->getLoginUser();
        if (empty($userInfo)) {
            return $this->fail(' 用户信息有误');
        }
        if (!empty($orderInfo)) {
            $money = $orderInfo->money;
            $app = new Application($this->config);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => env('MCHID'), // <---- 请修改为您的商户号
                "out_trade_no" => $orderSn,
                "appid" => env('APPID'), // <---- 请修改为服务号的 appid
                "description" => "快递付款",
                "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/callback",
                "amount" => [
                    "total" => (int)(bcmul($money, '100')),

                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => $userInfo->open_id, // <---- 请修改为服务号下单用户的 openid
                ]
            ]);


        } elseif (!empty($orderInfo2)) {
            $orderInfo = $orderInfo2;
            $money = $orderInfo->overweight_money;
            $app = new Application($this->config);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => env('MCHID'), // <---- 请修改为您的商户号
                "out_trade_no" => $orderSn,
                "appid" => env('APPID'), // <---- 请修改为服务号的 appid
                "description" => "快递补缴",
                "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/callback",
                "amount" => [
                    "total" => (int)(bcmul($money, '100')),
                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => $userInfo->open_id, // <---- 请修改为服务号下单用户的 openid
                ]
            ]);
        } else {
            return $this->fail('订单信息有误');
        }
        $prepayId = $response->toArray()['prepay_id'];
        if (empty($prepayId)) {
            return $this->fail('订单信息有误');
        }
        $utils = $app->getUtils();
        $config = $utils->buildMiniAppConfig($prepayId, env('APPID'));

        return $this->data($config);
    }

    public function getFilmPayInfo($orderSn)
    {

        $orderInfo = FilmOrder::where('order_sn', $orderSn)->where('status', 0)->first();
        $userInfo = $this->getLoginUser();
        if (empty($userInfo)) {
            return $this->fail(' 用户信息有误');
        }
        if (!empty($orderInfo)) {
            $money = $orderInfo->paid_price;
            $app = new Application($this->config);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => env('MCHID'), // <---- 请修改为您的商户号
                "out_trade_no" => $orderSn,
                "appid" => env('APPID'), // <---- 请修改为服务号的 appid
                "description" => "电影付款",
                "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/film_callback",
                "amount" => [
                    "total" => (int)(bcmul($money, '100')),
//                    "total" => 1,
                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => $userInfo->open_id, // <---- 请修改为服务号下单用户的 openid
                ]
            ]);


        }else {
            return $this->fail('订单信息有误');
        }
        $prepayId = $response->toArray()['prepay_id'];
        if (empty($prepayId)) {
            return $this->fail('订单信息有误');
        }
        $utils = $app->getUtils();
        $config = $utils->buildMiniAppConfig($prepayId, env('APPID'));

        return $this->data($config);
    }

    /**
     * @return \Psr\Http\Message\ResponseInterface
     * 升级订单回调
     */
    public function levelCallback()
    {
        $app = new Application($this->config);
        $server = $app->getServer();
        //支付回调
        $server->handlePaid(function (Message $message, \Closure $next) {
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = LevelOrders::where('order_sn', $orderSn)->where('status', 0)->first();
            $orderInfo->status = 1;
            $orderInfo->save();
            $userId = $orderInfo->user_id;
            $memberInfo = Members::find($userId);
            $memberInfo->user_level = 1;
            $memberInfo->v1_buy_status = 1;
            $memberInfo->save();
            $this->levelProfit($orderInfo->user_id, $orderInfo->id);
        });
        $server->handleRefunded(function (Message $message, \Closure $next) {
            //订单改为取消状态
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = LevelOrders::where('order_sn', $orderSn)->first();
            $userId = $orderInfo->user_id;
            $memberInfo = Members::find($userId);
            $memberInfo->user_level = 0;
            $memberInfo->v1_buy_status = 0;
            $memberInfo->save();
            MembersWithdraw::where('out_biz_no', $orderSn)->update(['status' => 2]);
            MembersProfit::where('user_id', $userId)->update(['status' => 2]); //所有订单全部失效
            $orderInfo->delete(true);
        });
        return $server->serve();
    }

    /**
     * @return \Psr\Http\Message\ResponseInterface
     * @throws InvalidArgumentException
     * @throws RuntimeException
     * @throws \ReflectionException
     * @throws \Throwable
     * 电影支付回调
     */
    public function filmCallback()
    {
        $app = new Application($this->config);
        $server = $app->getServer();
        //支付回调
        $server->handlePaid(function (Message $message, \Closure $next) {
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = FilmOrder::where('order_sn', $orderSn)->where('is_paid', 0)->first();
            $orderInfo->is_paid = 1;
            $orderInfo->paid_at = time();
            $orderInfo->save();
            $service = new FilmService();
            $result = $service->createOrder($orderSn);
        });
        $server->handleRefunded(function (Message $message, \Closure $next) {
            //订单改为取消状态
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = FilmOrder::where('order_sn', $orderSn)->first();
            $orderInfo->status = 2;
            $orderInfo->save();
        });
        return $server->serve();
    }

    /**
     * @throws InvalidArgumentException
     * @throws \Throwable
     * @throws \ReflectionException
     * @throws RuntimeException
     * 支付退款回调
     */
    public function callback(Request $request)
    {
        $app = new Application($this->config);
        $server = $app->getServer();
        //支付回调
        $server->handlePaid(function (Message $message, \Closure $next) {
            Log::info($message);
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = Orders::where('order_sn', $orderSn)->first();
            if (!empty($orderInfo)) {

                //返佣以及记录
                if (!empty($orderInfo->coupon_id)) {
                    $useCoupon = true;
                } else {
                    $useCoupon = false;
                }
                //首重续重分销计算
                $push['orderId'] = $orderInfo->id;
                $push['userId'] = $orderInfo->user_id;
                $push['useCoupon'] = $useCoupon;
                $push['first'] = true;
                if ($orderInfo->weight > 1) {
                    $push['more'] = true;
                    $push['calWeight'] = bcsub((string)$orderInfo->weight, '1');
                }
                $push['platform'] = $orderInfo->platform_id;
                //分销推送
                MemberProfitTask::dispatch($push);
                $data = [];
                $data['channelTag'] = $orderInfo->channel_tag;  //快递中文名称
                $data['channelId'] = $orderInfo->channel_id;  //快递中文名称
                $data['tag_type'] = $orderInfo->tag_type;  //快递中文名称
                $data['sender'] = $orderInfo->sender;
                $data['senderMobile'] = $orderInfo->sender_mobile;
                $data['senderProvince'] = $orderInfo->sender_province;
                $data['senderCity'] = $orderInfo->sender_city;
                $data['senderCounty'] = $orderInfo->sender_county;
//            $data['senderTown'] = $orderInfo->sender_town;
                $data['senderLocation'] = $orderInfo->sender_location;
                $data['senderAddress'] = $orderInfo->sender_address;
                $data['receiver'] = $orderInfo->receiver;
                $data['receiverMobile'] = $orderInfo->receiver_mobile;
                $data['receiveProvince'] = $orderInfo->receive_province;
                $data['receiveCity'] = $orderInfo->receive_city;
//            $data['receiveTown'] = $orderInfo->receive_town;
                $data['receiveCounty'] = $orderInfo->receive_county;
                $data['receiveLocation'] = $orderInfo->receive_location;
                $data['receiveAddress'] = $orderInfo->receive_address;
                $data['weight'] = $orderInfo->weight;
                $data['itemName'] = $orderInfo->item_name;  //物品名称
                $data['packageCount'] = (int)$orderInfo->package_count; //包裹数量
                $data['billRemark'] = $orderInfo->bill_remark; //订单备注
                $data['insured'] = $orderInfo->insured ?? 0; //订单备注
                //未付款才可以回调
                if ($orderInfo->status == 0) {
                    $orderInfo->status = 1;
                    $orderInfo->paid_at = time();
                    if ($orderInfo->channel_type == 'yida') {
                        //易达下单
                        $data['deliveryType'] = $orderInfo->tag_str;
                        $data['thirdNo'] = $orderInfo->order_sn;
                        $json = (new YidaService)->createOrder($data);
                        Log::info($json);
                        $result = json_decode($json, true);
                        if ($result['code'] != 200) {
                            $refundStatus = $this->refundOrder($orderSn, $orderInfo->money);
                            if ($refundStatus) {
                                $orderInfo->type = '已退款';
                                $orderInfo->type_code = 5;
                                $orderInfo->status = 2;
                                $orderInfo->cancel_remark = $result['msg'];
                                $orderInfo->save();
                            }

                        } elseif ($result['code'] == 200) {
                            $orderInfo->type = '待揽收';
                            $orderInfo->type_code = 1;
                            $orderInfo->waybill = $result['data']['deliveryId'];
                            $orderInfo->save();
                        }
                    } else {
                        $json = (new YunyangService)->createOrder($data);
                        Log::info($json);
                        $result = json_decode($json, true);
                        if ($result['code'] == 1) {
                            AddPostmanInfo::dispatch($orderInfo->id, 1);
                            $result2 = $result['result'];
                            $orderInfo->platform_id = $result2['billType'];
                            $orderInfo->waybill = $result2['waybill'];
                            $orderInfo->type = $result2['type'];
                            $orderInfo->type_code = $result2['typeCode'];
                            $orderInfo->save();
                            //用户下单数量+1
                            Members::where('id', $orderInfo->user_id)->increment('over_count');
                        } else {
                            $refundStatus = $this->refundOrder($orderSn, $orderInfo->money);
                            if ($refundStatus) {
                                $orderInfo->type = '已退款';
                                $orderInfo->type_code = 5;
                                $orderInfo->status = 2;
                                $orderInfo->cancel_remark = $result['message'];
                                $orderInfo->save();
                            }

                        }
                    }

                }
            } else {
                //快递补缴
                $orderInfo = Orders::where('overweight_sn', $orderSn)->first();
                $orderInfo->overweight_paid_at = time();
                $orderInfo->save();
                //增加余额变动日志
                $priceLog = [];
                $priceLog = new MembersPriceLog();
                $priceLog->user_id = $priceLog['start_user_id'] = $orderInfo->user_id;
                $priceLog->money = $orderInfo->overweight_money;
                $priceLog->type = 1; //增加
                $priceLog->status = 1; //失效
                $priceLog->order_sn = $orderInfo->order_sn;
                $priceLog->waybill = $orderInfo->waybill;
                $priceLog->save();
            }

            return $next($message);

        });
        $server->handleRefunded(function (Message $message, \Closure $next) {
            //订单改为取消状态
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = Orders::where('order_sn', $orderSn)->first();
            $openId = Members::where('id', $orderInfo->user_id)->value('open_id');
            $refundMoney = isset($message->amount->refund) ? $message->amount->refund : $orderInfo->money;
            //退款通知
            $message = [];
            $message['character_string1'] = ['value' => $orderInfo->waybill];
            $message['amount2'] = ['value' => $refundMoney];
            $message['time3'] = Carbon::now();
            $message['thing5'] = ['value' => '退款到账请注意查收'];
            $obj = (object)$message;
            $wechat = new WechatController();
            $page = '/pages/index/index.vue';
            $wechat->sendMessage('Ge9zDRUyCrSiBtzwdP_Px2kMFBQ7B08y6q2izfCquk0', $openId, $obj, $page);

            //用户佣金变为失效状态
            MembersProfit::where('order_id', $orderInfo->id)->whereIn('type', [1, 3, 4])->update(['status' => 2]);

            //增加余额变动日志
            $priceLog = [];
            $priceLog = new MembersPriceLog();
            $priceLog->user_id = $orderInfo->user_id;
            $priceLog->start_user_id = $orderInfo->user_id;
            $priceLog->money = $refundMoney;
            $priceLog->type = 1; //增加
            $priceLog->status = 2; //失效
            $priceLog->order_sn = $orderInfo->order_sn;
            $priceLog->waybill = $orderInfo->waybill;
            $priceLog->save();
            $refund = new RefundRecord();
            $refund->user_id = $orderInfo->user_id;
            $refund->order_id = $orderInfo->id;
            $refund->channel_type = $orderInfo->channel_type;
            $refund->refund_money = $refundMoney;
            $refund->save();
            return $next($message);
        });
        return $server->serve();
    }


    public function levelProfit($userId, $orderId)
    {
        $orderInfo = LevelOrders::find($orderId);
        $money = $orderInfo->money;
        $path = Redis::hget($userId, 'path');
        if (!empty($path)) {
            $pathArr = explode(",", $path);
            $pathArr = array_reverse($pathArr);
            $v1Count = 0;
            $v2Count = 0;
            $profit = [];
            foreach ($pathArr as $v) {
                $pinfo = Members::find($v);
                //v0-v1
                if ($pinfo->user_level == 1 && $v1Count == 0 && $v2Count == 0) {
                    $v1Count = 1;
                    $profit[] = $v;
                } //v0-v2
                elseif ($pinfo->user_level == 2 && $v1Count == 0 && $v2Count == 0) {
                    $v2Count = 1;
                    $profit[] = $v;
                } //v0-v1-v1
                elseif ($pinfo->user_level == 1 && $v1Count == 1 && $v2Count == 0) {
                    $v1Count = 2;
                    $profit[] = $v;
                    break;
                } //v0-v1-v2
                elseif ($pinfo->user_level == 2 && $v1Count == 1 && $v2Count == 0) {
                    $v2Count = 1;
                    $profit[] = $v;
                    break;
                } //v0-v2-v2
                elseif ($pinfo->user_level == 2 && $v1Count == 0 && $v2Count == 1) {
                    $v2Count = 2;
                    $profit[] = $v;
                    break;
                }
            }
            //返利
            if (!empty($profit)) {
                $model = new MembersProfit();
                //v0-v1
                if ($v1Count == 1 && $v2Count == 0) {
                    $model->user_id = $profit[0];
                    $model->order_id = $orderId;
                    $model->profit = $money;
                    $model->type = 2;
                    $model->save();  //增加收益
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[0];
                    $withdraw->money = $money;
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[0];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = $money;
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();

                } //v0-v2
                elseif ($v1Count == 0 && $v2Count == 1) {
                    $model->user_id = $profit[0];
                    $model->order_id = $orderId;
                    $model->profit = $money;
                    $model->type = 2;
                    $model->save();
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[0];
                    $withdraw->money = $money;
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[0];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = $money;
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();
                } //v0-v1-v1
                elseif ($v1Count == 2 || $v2Count == 2) {
                    $model->user_id = $profit[0];
                    $model->order_id = $orderId;
                    $model->profit = bcmul($money, '0.5', 2);
                    $model->type = 2;
                    $model->save();
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[0];
                    $withdraw->money = bcmul($money, '0.5', 2);
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[0];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = bcmul($money, '0.5', 2);
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();
                    $model2 = new MembersProfit();
                    $model2->user_id = $profit[1];
                    $model2->profit = bcmul($money, '0.5', 2);
                    $model2->order_id = $orderId;
                    $model2->type = 2;
                    $model2->save();
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[1];
                    $withdraw->money = bcmul($money, '0.5', 2);
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[1];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = bcmul($money, '0.5', 2);
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();
                } elseif ($v1Count == 1 && $v2Count == 1) {
                    $model->user_id = $profit[0];
                    $model->order_id = $orderId;
                    $model->profit = bcmul($money, '0.4', 2);
                    $model->type = 2;
                    $model->save();
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[0];
                    $withdraw->money = bcmul($money, '0.4', 2);
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[0];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = bcmul($money, '0.4', 2);
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();
                    $model2 = new MembersProfit();
                    $model2->user_id = $profit[1];
                    $model2->profit = bcmul($money, '0.6', 2);
                    $model2->order_id = $orderId;
                    $model2->type = 2;
                    $model2->save();
                    $withdraw = new MembersWithdraw();
                    $withdraw->user_id = $profit[1];
                    $withdraw->money = bcmul($money, '0.6', 2);
                    $withdraw->out_biz_no = $orderInfo->order_sn;
                    $withdraw->type = 2;
                    $withdraw->save();
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $profit[1];
                    $priceLog->start_user_id = $userId;
                    $priceLog->money = bcmul($money, '0.6', 2);
                    $priceLog->type = 1; //减少
                    $priceLog->status = 0; //失效
                    $priceLog->save();
                }
            }
        }
    }


    /**
     * @param $orderSn
     * @param $refundMoney
     * @return bool
     * @throws InvalidArgumentException
     * 微信发起退款
     */
    public function refundOrder($orderSn, $refundMoney)
    {
        $orderInfo = Orders::where('order_sn', $orderSn)->first();
        $app = new Application($this->config);
        $orderRefundSn = uniqid();
        $response = $app->getClient()->postJson("v3/refund/domestic/refunds", [
            "out_trade_no" => $orderSn,
            "out_refund_no" => $orderRefundSn,
            "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/callback",
            "amount" => [
                "refund" => (int)(bcmul((string)$refundMoney, '100')),
                "total" => (int)(bcmul((string)$orderInfo->money, '100')),
                "currency" => "CNY"
            ]
        ]);
        if ($response->isFailed()) {
            Log::info('退款异常'.$response->getContent(false));
            return false;
        } else {
            $orderInfo->order_refund_sn = $orderRefundSn;

        }
        $orderInfo->save();


        $record = UserHasCoupons::where('user_id', $orderInfo->user_id)->where('status', 1)->where('coupon_id', $orderInfo->coupon_id)->first();
        if (!empty($record)) {
            $record->status = 0;
            $record->save();
        }
        return true;

    }


    public function getHaocaiPayInfo(Request $request)
    {
        $orderSn = $request->input('order_sn');
        $orderInfo = Orders::where('haocai_sn', $orderSn)->where('is_haocai',1)->first();
        $userInfo = $this->getLoginUser();
        if (empty($userInfo)) {
            return $this->fail(' 用户信息有误');
        }
        if (!empty($orderInfo)) {
            $money = $orderInfo->haocai_money;
            $app = new Application($this->config);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => env('MCHID'), // <---- 请修改为您的商户号
                "out_trade_no" => $orderInfo->haocai_sn,
                "appid" => env('APPID'), // <---- 请修改为服务号的 appid
                "description" => "耗材费补缴",
                "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/haocai_callback",
                "amount" => [
                    "total" => (int)(bcmul($money, '100')),
                    "currency" => "CNY"
                ],
                "payer" => [
                    "openid" => $userInfo->open_id, // <---- 请修改为服务号下单用户的 openid
                ]
            ]);


        }else {
            return $this->fail('订单信息有误');
        }
        $prepayId = $response->toArray()['prepay_id'];
        if (empty($prepayId)) {
            return $this->fail('订单信息有误');
        }
        $utils = $app->getUtils();
        $config = $utils->buildMiniAppConfig($prepayId, env('APPID'));

        return $this->data($config);
    }

    public function haocaiCallback(Request $request)
    {
        $app = new Application($this->config);
        $server = $app->getServer();
        //支付回调
        $server->handlePaid(function (Message $message, \Closure $next) {
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = Orders::where('haocai_sn', $orderSn)->first();
            $orderInfo->haocai_paid_at = time();
            $orderInfo->save();
        });
        return $server->serve();
    }


    /**
     * @param $orderSn
     * @param $refundMoney
     * @return bool
     * @throws InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * 耗材退款
     */
    public function haocaiRefund($orderSn, $refundMoney)
    {
        $orderInfo = Orders::where('haocai_sn', $orderSn)->first();
        $app = new Application($this->config);
        if (empty($orderInfo->haocai_refund_sn)) {
            $orderRefundSn = uniqid();
        } else {
            $orderRefundSn = $orderInfo->haocai_refund_sn;
        }

        $response = $app->getClient()->postJson("v3/refund/domestic/refunds", [
            "out_trade_no" => $orderSn,
            "out_refund_no" => $orderRefundSn,
            "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/haocai_refund_callback",
            "amount" => [
                "refund" => (int)(bcmul((string)$refundMoney, '100')),
                "total" => (int)(bcmul((string)$orderInfo->haocai_money, '100')),
                "currency" => "CNY"
            ]
        ]);
        if ($response->isFailed()) {
            return false;
        }
        return true;
    }

    public function haocaiRefundCallback()
    {
        $app = new Application($this->config);
        $server = $app->getServer();
        //支付回调
        $server->handleRefunded(function (Message $message, \Closure $next) {
            $orderSn = $message->out_trade_no; //获取商户订单号
            $orderInfo = Orders::where('haocai_sn', $orderSn)->first();
            $orderInfo->is_haocai = 0;
            $orderInfo->haocai_paid_at = 0;
            $orderInfo->save();
        });
        return $server->serve();
    }

    public function publish(Request $request)
    {
        $time = $request->get('timestamp');
        $nonce = $request->get('nonce');
        $str = $nonce . $time . $this->wechatToken;
        $sign = sha1($str);
        if ($sign == $request->get('signature')) {
            return $request->get('echostr');
        } else {
            return 'fail';
        }

    }

    public function sendMessage($templateId = '', $openId = '', $data = '', $page = '')
    {

        $app = new MiniApp($this->miniConfig);
        $accessToken = $app->getAccessToken();
        $api = $app->getClient();
        $response = $api->withAccessToken($accessToken)->postJson('/cgi-bin/message/subscribe/send', [
            'template_id' => $templateId,
            'touser' => $openId,
            'page' => $page,
            'data' => $data,
            'miniprogram_state' => 'formal',
            'lang' => 'zh_CN'
        ]);

    }

    /**
     * @throws InvalidArgumentException
     */
    public function sendOfficialMessage($user, $template, $data)
    {
         $app = new OfficialApp($this->officialConfig);
        $accessToken = $app->getAccessToken();
        $api = $app->getClient();
        $post = [
            'touser' => $user,
            'template_id' => $template,
            'data' => $data
        ];
        $response = $api->withAccessToken($accessToken)->postJson('/cgi-bin/message/template/send', $post);
        Log::info($response);
    }

    public function checkRefund($orderSn)
    {
        $orderInfo = Orders::where('order_sn', $orderSn)->first();
        $refundMoney = '1';

        //用户佣金变为失效状态
        MembersProfit::where('order_id', $orderInfo->id)->whereIn('type', [1, 3, 4])->update(['status' => 2]);

        //增加余额变动日志
        $priceLog = [];
        $priceLog = new MembersPriceLog();
        $priceLog->user_id = $orderInfo->user_id;
        $priceLog->start_user_id = $orderInfo->user_id;
        $priceLog->money = $refundMoney;
        $priceLog->type = 1; //增加
        $priceLog->status = 2; //失效
        $priceLog->order_sn = $orderInfo->order_sn;
        $priceLog->waybill = $orderInfo->waybill;
        $priceLog->save();
        $refund = new RefundRecord();
        $refund->user_id = $orderInfo->user_id;
        $refund->order_id = $orderInfo->id;
        $refund->channel_type = $orderInfo->channel_type;
        $refund->refund_money = $refundMoney;
        $refund->save();
    }

    public function test()
    {
        $pinfo = Members::find(100016);
        $orderInfo = Orders::find(3607);
        if (!empty($pinfo['gzh_open_id'])) {
            $data = [
                'character_string12' => ['value' => $orderInfo->order_sn],
                'character_string1' => ['value' => $orderInfo->waybill],
                'amount6' => ['value' => $orderInfo->money],
                'amount13' => ['value' => (string)0.1],
            ];
            $wechat = new WechatController();
            $wechat->sendOfficialMessage($pinfo['gzh_open_id'], "a5SwcAaVdMm6qHnMJJHNw_Jq8AumK8QOVRPp2vXCrRo", $data);
        }
    }

    public function refundFilmOrder(mixed $orderSn)
    {
        $orderInfo = FilmOrder::where('order_sn', $orderSn)->first();
        $app = new Application($this->config);
        $orderRefundSn = uniqid();
        $response = $app->getClient()->postJson("v3/refund/domestic/refunds", [
            "out_trade_no" => $orderSn,
            "out_refund_no" => $orderRefundSn,
            "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/film_callback",
            "amount" => [
                "refund" => (int)(bcmul((string)$orderInfo->paid_price, '100')),
                "total" => (int)(bcmul((string)$orderInfo->paid_price, '100')),
                "currency" => "CNY"
            ]
        ]);
        if ($response->isFailed()) {
            Log::info('退款异常'.$response->getContent(false));
            return false;
        } else {
            $orderInfo->order_refund_sn = $orderRefundSn;

        }
        $orderInfo->save();
        return true;
    }


}
